Player = {}
Player.__index = Player

function Player.Create(x, y)
  local ply = {}
  setmetatable(ply, Player)
  ply.id = math.random(99999)
  ply.pos = Vector2D.Create(x, y)
  ply.velocity = Vector2D.Create(0, 0)
  ply.gravity = 700
  ply.jump_height = 200
  ply.img = {
    ["idle"] = love.graphics.newImage("assets/cat_idle.png"),
    ["walk"] = love.graphics.newImage("assets/cat_walk.png"),
    ["jump"] = love.graphics.newImage("assets/cat_jump.png"),
    ["attack2"] = love.graphics.newImage("assets/cat_A2.png"),
    ["attack4"] = love.graphics.newImage("assets/cat_A4.png"),
    ["attack6"] = love.graphics.newImage("assets/cat_A6.png"),
    ["attack8"] = love.graphics.newImage("assets/cat_A8.png"),
    ["attack9"] = love.graphics.newImage("assets/cat_A9.png")
  }
  ply.img.idle:setFilter("nearest", "nearest")
  ply.img.walk:setFilter("nearest", "nearest")
  ply.img.attack4:setFilter("nearest", "nearest")
  ply.img.attack6:setFilter("nearest", "nearest")
  ply.img.attack8:setFilter("nearest", "nearest")
  ply.img.attack9:setFilter("nearest", "nearest")
  ply.anim = {
    ["idle"] = newAnimation(ply.img.idle, 20, 30, 0.08, 0, {1, 3}),
    ["walk"] = newAnimation(ply.img.walk, 20, 30, 0.1, 0),
    ["jump"] = newAnimation(ply.img.jump, 24, 32, 0.06, 0),
    ["attack2"] = newAnimation(ply.img.attack2, 25, 30, 0.06, 0),
    ["attack4"] = newAnimation(ply.img.attack4, 24, 30, 0.06, 0),
    ["attack6"] = newAnimation(ply.img.attack6, 24, 30, 0.06, 0),
    ["attack8"] = newAnimation(ply.img.attack8, 24, 30, 0.06, 0),
    ["attack9"] = newAnimation(ply.img.attack6, 24, 30, 0.06, 0)
  }
  ply.anim.idle:setMode("loop")
  ply.anim.walk:setMode("loop")
  ply.anim.jump:setMode("once")
  ply.anim.attack2:setMode("once")
  ply.anim.attack4:setMode("once")
  ply.anim.attack6:setMode("once")
  ply.anim.attack8:setMode("once")
  ply.anim.attack9:setMode("once")
  ply.atkSpam = false
  ply.canMove = true
  ply.onGround = true
  ply.isAttacking = false
  ply.scale = 1
  ply.state = ply.anim.idle
  ply.animQueue = nil
  return ply
end

function Player:Update(dt)
  local input = self:GetInput()
  self.state:update(dt)
  self:AnimHandler(input)
  self:Physics(dt, input)
end

function Player:NetworkUpdate(posx, posy, velx, vely)
  self.pos.x, self.pos.y, self.velocity.x, self.velocity.y = posx, posy, velx, vely
end

function Player:Draw()
  self.state:draw(self.pos.x, self.pos.y, 0, self.scale, math.abs(self.scale), 10)
end

function Player:GetInput()
  local keyInput = Vector2D.Create(0, 0)
  if (self.canMove) then
    if (love.keyboard.isDown(key.right)) then
      keyInput.x = 1
    elseif (love.keyboard.isDown(key.left)) then
      keyInput.x = -1
    end
    if (love.keyboard.isDown(key.jump)) then
        if (self.velocity.y == 0) then
            self.velocity.y = self.jump_height
            self.onGround = false
        end
    end
  end
  if (keyInput.x ~= 0) then self.scale = keyInput.x end
  return keyInput
end

function Player:Physics(dt, input)
  if (self.velocity.y ~= 0) then
    self.pos.y = self.pos.y - self.velocity.y * dt
    self.velocity.y = self.velocity.y - self.gravity * dt
    if (self.pos.y > 300) then
        self.velocity.y = 0
        self.pos.y = 300
    end
  else
    self.onGround = true
  end
  
  self.velocity.x = input.x * 50
  if (self.canMove) then
    self.pos.x = self.pos.x + self.velocity.x * dt
  end
end

function Player:AnimHandler(input)
  if (not love.keyboard.isDown(key.attack)) then
    self.atkSpam = false
  end
  
  if (self.isAttacking) then
    if (love.keyboard.isDown(key.attack) and not self.atkSpam) then
      self.atkSpam = true
      if (self.onGround) then
        if (self.state == self.anim.attack6) then
          self.animQueue = self.anim.attack2
        elseif (self.state == self.anim.attack2) then
          self.animQueue = self.anim.attack4
        elseif (self.state == self.anim.attack4) then
          self.animQueue = self.anim.attack8
        elseif (self.state == self.anim.attack8) then
          self.animQueue = self.anim.attack9
        else
          self.animQueue = self.anim.attack6
        end
        self.canMove = false
      end
    end
    
    if (not self.state.playing) then
      if (self.animQueue ~= nil) then
        self.state:reset()
        self.animQueue:reset()
        self.state = self.animQueue
        self.state:play()
        self.animQueue = nil
      else
        self.canMove = true
        self.isAttacking = false
        self.state = self.anim.idle
      end
    end
  else
    if (love.keyboard.isDown(key.attack) and not self.atkSpam) then
      self.atkSpam = true
      if (self.onGround) then
        self.canMove = false
        self.isAttacking = true
        self.state = self.anim.attack6
        self.state:reset()
        self.state:play()
      else
        self.canMove = true
        self.isAttacking = true
        self.state = self.anim.attack8
        self.state:reset()
        self.state:play()
      end
    elseif (self.onGround) then
      if (self.velocity.x ~= 0) then
        if (self.state ~= self.animWalk) then
          self.state = self.anim.walk
        end
      else
        if (self.state ~= self.animIdle) then
          self.state = self.anim.idle
        end
      end
    end
  end
end

function Player:FormatString(cmd)
  --format = id, cmd, x, y, velx, vely
  return string.format("%i %s %i %i %f %f", self.id, cmd, self.pos.x, self.pos.y, self.velocity.x, self.velocity.y)
end